#include "PlaceCommand.h"
#include "../view/UMLCanvas.h"

#include <algorithm>
#include <stdexcept>
#include <QDebug>

using std::runtime_error;

PlaceCommand::PlaceCommand(UMLDiagram& d, UMLCanvas& canvas, const UMLObject& o)
:	_diagram(d), _canvas(canvas), _prototype(o.clone()), _created(NULL)
{
}

PlaceCommand::PlaceCommand(const PlaceCommand& pc)
:	_diagram(pc._diagram), _canvas(pc._canvas),
	_prototype(pc._prototype->clone()), _created(pc._created)
{
	/* Unfortunately we do perform heap allocation in UMLObject::clone(), but
	 * this should be an uncommon operation. */
}

PlaceCommand::~PlaceCommand()
{
	delete _prototype;
}

UMLObject& PlaceCommand::prototype()
{
	if (_created)
		throw runtime_error("PlaceCommand has executed, prototype obsolete.");

	return *_prototype;
}

void PlaceCommand::execute()
{
	// Only use the prototype if we haven't executed before. Self-assign if we
	// already have.
	_created = &_diagram.add(
			(_created) ? *_created : *_prototype);

	qDebug() << "Created Object at logical "
		<< _created->position()
		<< _created->size();

	_canvas.clearSelection();
	_canvas.select(_created);
}

void PlaceCommand::unexecute()
{
	if (!_created)
		throw runtime_error(
				"PlaceCommand has not been executed, cannot unexecute!");

	UMLDiagram::iterator iter =
		find(_diagram.begin(), _diagram.end(), _created);

	if (iter == _diagram.end())
		throw runtime_error("PlaceCommand appears already unexecuted.");

	_diagram.remove(iter);
}

